package com.tanhua.dubbo.api.Impl;

import com.itheima.dubbo.api.MovementsApi;
import com.tanhua.dubbo.service.MovementsService;
import com.tanhua.dubbo.utils.IdWorker;
import com.tanhua.model.enums.CommentType;
import com.tanhua.model.mongoDb.Comment;
import com.tanhua.model.mongoDb.Movement;
import com.tanhua.model.mongoDb.MovementTimeLine;
import com.tanhua.model.vo.PageResult;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author Pan Rundong
 * @Date 2023-02-28 23:51
 * @Desc 动态Api实现类
 */
@DubboService
public class MovementsApiImpl implements MovementsApi {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private IdWorker idWorker;
    @Autowired
    private MovementsService movementsService;


    /**
     * 发布动态
     *
     * @param movement
     * @return void
     * @Author Pan Rundong
     */
    @Override
    public void publicMovements(Movement movement) {
        //1.储存信息，并通过userId查询好友信息
            //1.1 保存时间
        movement.setCreated(System.currentTimeMillis());
            //1.2 保存自增id
        movement.setPid(idWorker.getNextId("movement"));
            //1.3 储存
        mongoTemplate.save(movement);
        //2.调用异步请求
        movementsService.saveMovementsTimeLine(movement);
    }

    /**
     * 根据Id查询个人动态
     *
     * @param page
     * @param pagesize
     * @param userId
     * @return com.tanhua.model.vo.PageResult
     * @Author Pan Rundong
     */
    @Override
    public PageResult findById(Integer page, Integer pagesize, Long userId) {
        //1.创建对象
        Criteria criteria = Criteria.where("userId").is(userId);

        return getPageResult(page, pagesize, criteria);
    }



    /**
     * 根据Id查询好友动态
     *
     * @param page
     * @param pagesize
     * @param userId
     * @return com.tanhua.model.vo.PageResult
     * @Author Pan Rundong
     */
    @Override
    public PageResult friendsMovements(Integer page, Integer pagesize, Long userId) {
        //1.创建对象
        Criteria criteria = Criteria.where("friendId").is(userId);

        //2.设置条件查询friendId为userId的MovementTimeLine
        Query query = Query.query((criteria));
        List<MovementTimeLine> timeLineList = mongoTemplate.find(query, MovementTimeLine.class);

        //3.获得所有movementsId
        List<ObjectId> movementsIds = timeLineList.stream().map(item ->
            item.getMovementId()
        ).collect(Collectors.toList());

        //4.新建查询对象
        Criteria criteria1 = Criteria.where("id").in(movementsIds);

        //5.设置分页查询条件
        return getPageResult(page, pagesize, criteria1);
    }

    /**
     * 根据Pids获取动态
     *
     * @param page
     * @param pagesize
     * @param pids
     * @return com.tanhua.model.vo.PageResult
     * @Author Pan Rundong
     */
    @Override
    public PageResult recommend(Integer page, Integer pagesize, List<Long> pids) {
        //1.设置查询条件
        Query query = Query.query(Criteria.where("pid").in(pids));
        //2.算总数
        long count = mongoTemplate.count(query, Movement.class);
        //3.分页查询
        query.skip((page -1)* pagesize).limit(pagesize)
                .with(Sort.by(Sort.Order.desc("created")));
        //4.获取List
        List<Movement> movements = mongoTemplate.find(query, Movement.class);
        //5.返回
        return new PageResult(page, pagesize, (int) count, movements);
    }

    /**
     * 随机获取动态
     *
     * @param pagesize
     * @return com.tanhua.model.vo.PageResult
     * @Author Pan Rundong
     */
    @Override
    public PageResult randomRecommend(Integer pagesize) {
        //1、创建统计对象，设置统计参数
        TypedAggregation aggregation = Aggregation.newAggregation(Movement.class,Aggregation.sample(pagesize));
        //2、调用mongoTemplate方法统计
        AggregationResults<Movement> results = mongoTemplate.aggregate(aggregation, Movement.class);
        //3、获取统计结果
        List<Movement> mappedResults = results.getMappedResults();
        //4.返回
        return new PageResult(1, pagesize, pagesize, mappedResults);
    }

    /**
     * 根据动态Id获取动态信息
     *
     * @param id
     * @return com.tanhua.model.mongoDb.Movement
     * @Author Pan Rundong
     */
    @Override
    public Movement getById(String id) {
        Movement movement = mongoTemplate.findById(id, Movement.class);
        return movement;
    }

    /**
     * 动态点赞
     *
     * @param movementId
     * @param like
     * @param userId
     * @return java.lang.Boolean
     * @Author Pan Rundong
     */
    @Override
    public Boolean haveOrNot(String movementId, CommentType like, Long userId) {
        //1.设置条件
        Query query = Query.query(Criteria.where("publishId").is(movementId)
                .and("userId").is(userId)
                .and("commentType").is(like.getType()));
        //2.判断是否存在并返回
        return mongoTemplate.exists(query, Comment.class);
    }

    /**
     * 后台分页查询
     *
     * @param page
     * @param pagesize
     * @param uid
     * @param state
     * @return com.tanhua.model.vo.PageResult
     * @Author Pan Rundong
     */
    @Override
    public PageResult findByState(Integer page, Integer pagesize, Long uid, Integer state) {
        // 1.设置条件
        Query query = new Query();
        if (uid != null) {
            query.addCriteria(Criteria.where("userId").is(uid));
        }
        if (state != null) {
            query.addCriteria(Criteria.where("state").is(state));
        }
        //查询总数
        long count = mongoTemplate.count(query, Movement.class);
        //设置分页参数
        query.with(Sort.by(Sort.Order.desc("created"))).limit(pagesize).skip((page -1) * pagesize);

        List<Movement> list = mongoTemplate.find(query, Movement.class);
        return new PageResult(page, pagesize, (int) count, list);
    }

    /**
     * 获取分页查询
     *
     * @param page
     * @param pagesize
     * @param criteria
     * @return com.tanhua.model.vo.PageResult
     * @Author Pan Rundong
     */
    private PageResult getPageResult(Integer page, Integer pagesize, Criteria criteria) {
        //2.设置条件分页查询
        Query query  =  Query.query(criteria);
        long count = mongoTemplate.count(query, Movement.class);

        query.skip((page -1)* pagesize).limit(pagesize).with(Sort.by(Sort.Order.desc("created")));
        List<Movement> movements = mongoTemplate.find(query, Movement.class);
        //3.返回
        return new PageResult(page, pagesize, (int) count, movements);
    }
}
